#include "view.hpp"
#include "window.hpp"

#include "GL/glut.h"
#include <math.h>

#include "grab.h"
#include "objloader.h"
#include "objsaver.h"

// #define  GLUT_WHEEL_UP 3
// #define  GLUT_WHEEL_DOWN 4
#define PI 3.1415926535
#define CAMERA_STEP 0.5f

float eye[] = {0, 20, 50};
float center[] = {0, 1.5, 0};

float mousePrevPos[2] = {-1, -1};
float eyeAngle[] = {270, 0};
float fDist = 2.5; // Focusing distance(radius from eye position to focusing center)

void updateCenterPos(void){ // eye is at the center of the sphare
	center[0] = eye[0] + fDist * cos(eyeAngle[0] / 180 * PI);
	center[2] = eye[2] + fDist * sin(eyeAngle[0] / 180 * PI);
	center[1] = eye[1] + fDist * sin(eyeAngle[1] / 180 * PI);
}

void mouseKeyCallback(int button, int state, int x, int y) {
	if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
		//TODO: add selecting function
	}
}

void mouseMotionCallback(int x, int y) {
    if(mousePrevPos[0] == -1 && mousePrevPos[1] == -1){
		mousePrevPos[0] = wWidth / 2;
		mousePrevPos[1] = wHeight / 2;
		glutWarpPointer(wWidth / 2, wHeight / 2);
		return;
	}else{
		eyeAngle[0] += (x - mousePrevPos[0]) * 0.1;
		eyeAngle[1] += -(y - mousePrevPos[1]) * 0.1;
		if(eyeAngle[1] < -90) eyeAngle[1] = -90;
		else if(eyeAngle[1] > 90) eyeAngle[1] = 90;
		glutWarpPointer(wWidth / 2, wHeight / 2);
		mousePrevPos[0] = wWidth / 2;
		mousePrevPos[1] = wHeight / 2;
		updateCenterPos();
	}
}

void keyboardCallback(unsigned char k, int x, int y) {
	switch(k){
		case 27:
			exit(0);
			break; 
		case 'a':
			eye[0] += CAMERA_STEP * cos((eyeAngle[0] - 90) / 180 * PI);
			eye[2] += CAMERA_STEP * sin((eyeAngle[0] - 90) / 180 * PI);
			updateCenterPos();
			break;
		case 'd': 
			eye[0] += CAMERA_STEP * cos((eyeAngle[0] + 90) / 180 * PI);
			eye[2] += CAMERA_STEP * sin((eyeAngle[0] + 90) / 180 * PI);
			updateCenterPos();
			break;
		case 'w':
			eye[0] += CAMERA_STEP * cos(eyeAngle[0] / 180 * PI);
			eye[2] += CAMERA_STEP * sin(eyeAngle[0] / 180 * PI);
			updateCenterPos();
			break;
		case 's':
			eye[0] += CAMERA_STEP * cos((eyeAngle[0] + 180) / 180 * PI);
			eye[2] += CAMERA_STEP * sin((eyeAngle[0] + 180) / 180 * PI);
			updateCenterPos();
			break;
		case 'z':
			eye[1] -= CAMERA_STEP;
			updateCenterPos();
			break;
		case 'c':
			eye[1] += CAMERA_STEP;
			updateCenterPos();
			break;
		case 'g':
			grab(wWidth, wHeight);
			break;
		case 'o':

			ObjLoader test = ObjLoader("../obj/Porsche_911_GT2.obj");

			objsave(test.vSets, test.vtSets, test.vnSets, test.fSets);
			
			break;
	}
}

void updateView(void) {
    glViewport(0, 0, wWidth, wHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    float whRatio = (GLfloat)wWidth / (GLfloat)wHeight;
    gluPerspective(45.0f, whRatio, 1, 1000);
    glMatrixMode(GL_MODELVIEW);
}